package io.github.echarts.render.coordinate.cartesian;

import io.github.echarts.model.coordinate.DataRange;
import io.github.echarts.model.coordinate.axis.AxisModel;
import io.github.echarts.model.coordinate.cartesian.CartesianCoordinateTransformer;
import io.github.echarts.model.geometry.Rectangle;
import io.github.echarts.option.component.Axis;
import io.github.echarts.option.component.axis.AxisLabel;
import io.github.echarts.option.component.axis.AxisLine;
import io.github.echarts.option.component.axis.AxisTick;
import io.github.echarts.option.component.axis.SplitLine;
import io.github.echarts.render.GraphicsRenderer;
import io.github.echarts.render.svg.SVGLayerType;

import java.awt.Font;
import java.util.List;

/**
 * 坐标轴渲染器，负责渲染坐标轴的各个部分
 */
public class AxisRenderer {
    // 轴线默认颜色
    private static final String DEFAULT_AXIS_LINE_COLOR = "#333";
    // 轴线默认宽度
    private static final int DEFAULT_AXIS_LINE_WIDTH = 1;
    // 刻度线默认长度
    private static final int DEFAULT_TICK_LENGTH = 5;
    // 轴标签与轴线的默认距离
    private static final int DEFAULT_LABEL_DISTANCE = 8;
    // 默认字体
    private static final Font DEFAULT_FONT = new Font("Arial", Font.PLAIN, 12);
    // 默认文本颜色
    private static final String DEFAULT_TEXT_COLOR = "#666";
    // 网格线默认颜色
    private static final String DEFAULT_GRID_LINE_COLOR = "#e0e0e0";
    // 网格线默认宽度
    private static final int DEFAULT_GRID_LINE_WIDTH = 1;
    // 网格线默认类型
    private static final String DEFAULT_GRID_LINE_TYPE = "dashed";

    /**
     * 渲染X轴
     * 
     * @param renderer 图形渲染器
     * @param xAxisModel X轴模型
     * @param area 坐标系区域
     * @param transformer 坐标转换器
     */
    public void renderXAxis(GraphicsRenderer renderer, AxisModel xAxisModel, Rectangle area, CartesianCoordinateTransformer transformer) {
        if (xAxisModel == null || !Boolean.TRUE.equals(xAxisModel.getAxis().getShow())) {
            return;
        }

        Axis xAxis = xAxisModel.getAxis();
        
        // 确定X轴位置（顶部或底部）
        boolean isTop = "top".equals(xAxis.getPosition());
        int axisY = isTop ? (int)area.getY() : (int)(area.getY() + area.getHeight());

        // 渲染轴线
        renderXAxisLine(renderer, xAxis, area, axisY);

        // 渲染刻度和标签
        if (xAxisModel.isCategoryAxis()) {
            renderCategoryAxis(renderer, xAxisModel, area, transformer, axisY, isTop);
        } else {
            renderValueXAxis(renderer, xAxisModel, area, transformer, axisY, isTop);
        }

        // 渲染网格线
        renderXGridLines(renderer, xAxisModel, area, transformer);
    }

    /**
     * 渲染Y轴
     * 
     * @param renderer 图形渲染器
     * @param yAxisModel Y轴模型
     * @param area 坐标系区域
     * @param transformer 坐标转换器
     */
    public void renderYAxis(GraphicsRenderer renderer, AxisModel yAxisModel, Rectangle area, 
            CartesianCoordinateTransformer transformer) {
        if (yAxisModel == null || !Boolean.TRUE.equals(yAxisModel.getAxis().getShow())) {
            return;
        }

        Axis yAxis = yAxisModel.getAxis();
        
        // 确定Y轴位置（左侧或右侧）
        boolean isRight = "right".equals(yAxis.getPosition());
        int axisX = isRight ? (int)(area.getX() + area.getWidth()) : (int)area.getX();

        // 渲染轴线
        renderYAxisLine(renderer, yAxis, area, axisX);

        // 渲染刻度和标签
        renderValueYAxis(renderer, yAxisModel, area, transformer, axisX, isRight);

        // 渲染网格线
        renderYGridLines(renderer, yAxisModel, area, transformer);
    }

    /**
     * 渲染X轴线
     */
    private void renderXAxisLine(GraphicsRenderer renderer, Axis xAxis, Rectangle area, int axisY) {
        AxisLine axisLine = xAxis.getAxisLine();
        if (axisLine == null || !Boolean.TRUE.equals(axisLine.getShow())) {
            return;
        }

        String color = DEFAULT_AXIS_LINE_COLOR;
        int width = DEFAULT_AXIS_LINE_WIDTH;

        if (axisLine.getLineStyle() != null) {
            color = axisLine.getLineStyle().getColor() != null ? 
                    axisLine.getLineStyle().getColor() : color;
        }
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 切换到坐标轴层
        renderer.setCurrentLayer(SVGLayerType.AXIS);

        // 绘制轴线
        renderer.drawLine(
                (int)area.getX(), 
                axisY, 
                (int)(area.getX() + area.getWidth()), 
                axisY, 
                color, 
                width, 
                "solid"
        );
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }

    /**
     * 渲染Y轴线
     */
    private void renderYAxisLine(GraphicsRenderer renderer, Axis yAxis, Rectangle area, int axisX) {
        AxisLine axisLine = yAxis.getAxisLine();
        if (axisLine == null || !Boolean.TRUE.equals(axisLine.getShow())) {
            return;
        }

        String color = DEFAULT_AXIS_LINE_COLOR;
        int width = DEFAULT_AXIS_LINE_WIDTH;

        if (axisLine.getLineStyle() != null) {
            color = axisLine.getLineStyle().getColor() != null ? 
                    axisLine.getLineStyle().getColor() : color;
        }
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 切换到坐标轴层
        renderer.setCurrentLayer(SVGLayerType.AXIS);

        // 绘制轴线
        renderer.drawLine(
                axisX, 
                (int)area.getY(), 
                axisX, 
                (int)(area.getY() + area.getHeight()), 
                color, 
                width, 
                "solid"
        );
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }

    /**
     * 渲染类别轴（通常是X轴）
     */
    private void renderCategoryAxis(GraphicsRenderer renderer, AxisModel axisModel, Rectangle area, 
            CartesianCoordinateTransformer transformer, int axisY, boolean isTop) {
        
        Axis axis = axisModel.getAxis();
        int categoryCount = axisModel.getCategoryCount();
        if (categoryCount == 0) {
            return;
        }

        // 计算每个类别的宽度
        double unitWidth = area.getWidth() / categoryCount;
        
        // 获取刻度配置
        AxisTick axisTick = axis.getAxisTick();
        boolean showTick = axisTick != null && Boolean.TRUE.equals(axisTick.getShow());
        int tickLength = showTick ? 
                (axisTick.getLength() != null ? axisTick.getLength() : DEFAULT_TICK_LENGTH) : 0;
        
        // 刻度方向
        int tickDirection = isTop ? -1 : 1;
        
        // 获取标签配置
        AxisLabel axisLabel = axis.getAxisLabel();
        boolean showLabel = axisLabel == null || axisLabel.getShow() == null || Boolean.TRUE.equals(axisLabel.getShow());
        int labelDistance = axisLabel != null && axisLabel.getDistance() != null ? 
                axisLabel.getDistance() : DEFAULT_LABEL_DISTANCE;
        
        // 标签位置偏移
        int labelOffset = tickLength + labelDistance;
        int labelY = isTop ? axisY - labelOffset : axisY + labelOffset;
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 渲染每个类别的刻度和标签
        for (int i = 0; i < categoryCount; i++) {
            // 计算当前类别的中心位置
            double centerRatio = (i + 0.5) / categoryCount;
            int centerX = (int) transformer.transformX(centerRatio);
            
            // 切换到坐标轴层渲染刻度线
            renderer.setCurrentLayer(SVGLayerType.AXIS);
            if (showTick) {
                renderer.drawLine(
                        centerX, 
                        axisY, 
                        centerX, 
                        axisY + tickLength * tickDirection, 
                        DEFAULT_AXIS_LINE_COLOR, 
                        DEFAULT_AXIS_LINE_WIDTH, 
                        "solid"
                );
            }
            
            // 切换到标签层渲染标签
            renderer.setCurrentLayer(SVGLayerType.LABEL);
            if (showLabel) {
                Object category = axisModel.getCategory(i);
                String text = category != null ? String.valueOf(category) : "";
                
                // 调整labelY以确保文本与刻度对齐
                int adjustedLabelY = isTop ? labelY - 5 : labelY + 5;
                
                renderer.drawText(
                        text, 
                        centerX, 
                        adjustedLabelY, 
                        DEFAULT_FONT, 
                        DEFAULT_TEXT_COLOR, 
                        "center"
                );
            }
        }
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }

    /**
     * 渲染数值X轴
     */
    private void renderValueXAxis(GraphicsRenderer renderer, AxisModel axisModel, Rectangle area, 
            CartesianCoordinateTransformer transformer, int axisY, boolean isTop) {
        
        Axis axis = axisModel.getAxis();
        
        // 获取数据范围
        DataRange dataRange = axisModel.getDataRange();
        if (dataRange == null) {
            return;
        }
        
        // 获取刻度值列表
        List<Double> ticks = axisModel.generateTicks();
        if (ticks.isEmpty()) {
            return;
        }
        
        // 获取刻度配置
        AxisTick axisTick = axis.getAxisTick();
        boolean showTick = axisTick != null && Boolean.TRUE.equals(axisTick.getShow());
        int tickLength = showTick ? 
                (axisTick.getLength() != null ? axisTick.getLength() : DEFAULT_TICK_LENGTH) : 0;
        
        // 刻度方向
        int tickDirection = isTop ? -1 : 1;
        
        // 获取标签配置
        AxisLabel axisLabel = axis.getAxisLabel();
        boolean showLabel = axisLabel == null || axisLabel.getShow() == null || Boolean.TRUE.equals(axisLabel.getShow());
        int labelDistance = axisLabel != null && axisLabel.getDistance() != null ? 
                axisLabel.getDistance() : DEFAULT_LABEL_DISTANCE;
        
        // 标签位置偏移
        int labelOffset = tickLength + labelDistance;
        int labelY = isTop ? axisY - labelOffset : axisY + labelOffset;
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 渲染每个刻度和标签
        for (Double value : ticks) {
            double ratio = dataRange.normalize(value);
            int x = (int) transformer.transformX(ratio);
            
            // 切换到坐标轴层渲染刻度线
            renderer.setCurrentLayer(SVGLayerType.AXIS);
            if (showTick) {
                renderer.drawLine(
                        x, 
                        axisY, 
                        x, 
                        axisY + tickLength * tickDirection, 
                        DEFAULT_AXIS_LINE_COLOR, 
                        DEFAULT_AXIS_LINE_WIDTH, 
                        "solid"
                );
            }
            
            // 切换到标签层渲染标签
            renderer.setCurrentLayer(SVGLayerType.LABEL);
            if (showLabel) {
                String text = axisModel.formatLabel(value);
                
                // 调整labelY以确保文本与刻度对齐
                int adjustedLabelY = isTop ? labelY - 5 : labelY + 5;
                
                renderer.drawText(
                        text, 
                        x, 
                        adjustedLabelY, 
                        DEFAULT_FONT, 
                        DEFAULT_TEXT_COLOR, 
                        "center"
                );
            }
        }
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }

    /**
     * 渲染数值Y轴
     */
    private void renderValueYAxis(GraphicsRenderer renderer, AxisModel axisModel, Rectangle area, 
            CartesianCoordinateTransformer transformer, int axisX, boolean isRight) {
        
        Axis axis = axisModel.getAxis();
        
        // 获取数据范围
        DataRange dataRange = axisModel.getDataRange();
        if (dataRange == null) {
            return;
        }
        
        // 获取刻度值列表
        List<Double> ticks = axisModel.generateTicks();
        if (ticks.isEmpty()) {
            return;
        }
        
        // 获取刻度配置
        AxisTick axisTick = axis.getAxisTick();
        boolean showTick = axisTick != null && Boolean.TRUE.equals(axisTick.getShow());
        int tickLength = showTick ? 
                (axisTick.getLength() != null ? axisTick.getLength() : DEFAULT_TICK_LENGTH) : 0;
        
        // 刻度方向
        int tickDirection = isRight ? 1 : -1;
        
        // 获取标签配置
        AxisLabel axisLabel = axis.getAxisLabel();
        boolean showLabel = axisLabel == null || axisLabel.getShow() == null || Boolean.TRUE.equals(axisLabel.getShow());
        int labelDistance = axisLabel != null && axisLabel.getDistance() != null ? 
                axisLabel.getDistance() : DEFAULT_LABEL_DISTANCE;
        
        // 标签位置偏移
        int labelOffset = tickLength + labelDistance;
        int labelX = isRight ? axisX + labelOffset : axisX - labelOffset;
        String align = isRight ? "left" : "right";
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 渲染每个刻度和标签
        for (Double value : ticks) {
            double ratio = dataRange.normalize(value);
            int y = (int) transformer.transformY(ratio);
            
            // 切换到坐标轴层渲染刻度线
            renderer.setCurrentLayer(SVGLayerType.AXIS);
            if (showTick) {
                renderer.drawLine(
                        axisX, 
                        y, 
                        axisX + tickLength * tickDirection, 
                        y, 
                        DEFAULT_AXIS_LINE_COLOR, 
                        DEFAULT_AXIS_LINE_WIDTH, 
                        "solid"
                );
            }
            
            // 切换到标签层渲染标签
            renderer.setCurrentLayer(SVGLayerType.LABEL);
            if (showLabel) {
                String text = axisModel.formatLabel(value);
                
                // 调整labelX以确保文本与刻度对齐
                int adjustedLabelX = isRight ? labelX + 5 : labelX - 5;
                
                renderer.drawText(
                        text, 
                        adjustedLabelX, 
                        y, 
                        DEFAULT_FONT, 
                        DEFAULT_TEXT_COLOR, 
                        align
                );
            }
        }
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }

    /**
     * 渲染X轴网格线
     */
    private void renderXGridLines(GraphicsRenderer renderer, AxisModel axisModel, Rectangle area, 
            CartesianCoordinateTransformer transformer) {
        
        Axis axis = axisModel.getAxis();
        SplitLine splitLine = axis.getSplitLine();
        if (splitLine == null || !Boolean.TRUE.equals(splitLine.getShow())) {
            return;
        }

        String lineColor = DEFAULT_GRID_LINE_COLOR;
        int lineWidth = DEFAULT_GRID_LINE_WIDTH;
        String lineType = DEFAULT_GRID_LINE_TYPE;

        if (splitLine.getLineStyle() != null) {
            if (splitLine.getLineStyle().getColor() != null) {
                lineColor = splitLine.getLineStyle().getColor();
            }
            if (splitLine.getLineStyle().getWidth() != null) {
                lineWidth = splitLine.getLineStyle().getWidth();
            }
            if (splitLine.getLineStyle().getType() != null) {
                lineType = splitLine.getLineStyle().getType();
            }
        }
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 切换到网格线层
        renderer.setCurrentLayer(SVGLayerType.GRID);

        // 对于类别轴
        if (axisModel.isCategoryAxis()) {
            int categoryCount = axisModel.getCategoryCount();
            
            for (int i = 0; i < categoryCount; i++) {
                // 计算当前类别的中心位置
                double centerRatio = (i + 0.5) / categoryCount;
                int centerX = (int) transformer.transformX(centerRatio);
                
                // 绘制垂直网格线
                renderer.drawGridLine(
                        centerX,
                        (int) area.getY(),
                        centerX,
                        (int) (area.getY() + area.getHeight()),
                        lineColor,
                        lineWidth,
                        lineType
                );
            }
        } else {
            // 对于数值轴
            List<Double> ticks = axisModel.generateTicks();
            
            if (!ticks.isEmpty()) {
                DataRange dataRange = axisModel.getDataRange();
                
                // 绘制网格线
                for (Double value : ticks) {
                    double ratio = dataRange.normalize(value);
                    int x = (int) transformer.transformX(ratio);
                    
                    renderer.drawGridLine(
                            x,
                            (int) area.getY(),
                            x,
                            (int) (area.getY() + area.getHeight()),
                            lineColor,
                            lineWidth,
                            lineType
                    );
                }
            }
        }
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }

    /**
     * 渲染Y轴网格线
     */
    private void renderYGridLines(GraphicsRenderer renderer, AxisModel axisModel, Rectangle area, 
            CartesianCoordinateTransformer transformer) {
        
        Axis axis = axisModel.getAxis();
        SplitLine splitLine = axis.getSplitLine();
        if (splitLine == null || !Boolean.TRUE.equals(splitLine.getShow())) {
            return;
        }

        String lineColor = DEFAULT_GRID_LINE_COLOR;
        int lineWidth = DEFAULT_GRID_LINE_WIDTH;
        String lineType = DEFAULT_GRID_LINE_TYPE;

        if (splitLine.getLineStyle() != null) {
            if (splitLine.getLineStyle().getColor() != null) {
                lineColor = splitLine.getLineStyle().getColor();
            }
            if (splitLine.getLineStyle().getWidth() != null) {
                lineWidth = splitLine.getLineStyle().getWidth();
            }
            if (splitLine.getLineStyle().getType() != null) {
                lineType = splitLine.getLineStyle().getType();
            }
        }
        
        // 保存当前图层
        String originalLayer = renderer.getCurrentLayer();
        
        // 切换到网格线层
        renderer.setCurrentLayer(SVGLayerType.GRID);

        // 获取刻度值列表
        List<Double> ticks = axisModel.generateTicks();
        
        if (!ticks.isEmpty()) {
            DataRange dataRange = axisModel.getDataRange();
            
            // 绘制网格线
            for (Double value : ticks) {
                double ratio = dataRange.normalize(value);
                int y = (int) transformer.transformY(ratio);
                
                renderer.drawGridLine(
                        (int) area.getX(),
                        y,
                        (int) (area.getX() + area.getWidth()),
                        y,
                        lineColor,
                        lineWidth,
                        lineType
                );
            }
        }
        
        // 恢复原始图层
        renderer.setCurrentLayer(originalLayer);
    }
} 